﻿function Powerpack
{
    param(
          [Parameter(Position=0)]
          [Scriptblock]
          $Definition,
          [Parameter()]
          [String]
          $Id
         )
    $xml = New-Object System.Xml.XmlDocument
    $declaration = $xml.CreateXmlDeclaration('1.0', 'utf-8', $null)
    
    $null = $xml.AppendChild($declaration)
    
    $configuration = $xml.CreateElement('configuration')
    $null = $xml.AppendChild($configuration)
    
    if($Id)
    {
        $configuration.SetAttribute('id', $Id)
    }
    else
    {
        $configuration.SetAttribute('id', ([Guid]::NewGuid()).ToString())
    }
    
    $infoContainer = $xml.CreateElement('container') 
    $infoContainer.SetAttribute('name', 'PowerPack Info')
    $infoContainer.SetAttribute('id', 'f5f11900-7edc-47f6-9efa-87abd9d5df07')
    $null = $configuration.AppendChild($infoContainer)
    
    function Info
    {
        param(
              [Parameter(Mandatory=$true)]
              [String]
              $Name,
              [Parameter()]
              [String]
              $Description,
              [Parameter()]
              [String]
              $Version,
              [Parameter()]
              [String]
              $Url,
              [Parameter()]
              [String]
              $HomePage,
              [Parameter()]
              [String]
              $ConsoleVersion,
              [Parameter()]
              [ScriptBlock]
              $Definition
             )
        
        #container name="PowerPack Name" id="01f58085-d817-4d04-8316-f978e8674b7e"
        $nameContainer = $xml.CreateElement('container')
        $nameContainer.SetAttribute('name', 'PowerPack Name')
        $nameContainer.SetAttribute('id', '01f58085-d817-4d04-8316-f978e8674b7e')
        $nameValue = $xml.CreateElement('value')
        $nameValue.InnerText = $Name
        
        $null = $nameContainer.AppendChild($nameValue)
        $null = $infoContainer.AppendChild($nameContainer)
        
        #container name="Description" id="2a7a09ae-54f3-468b-a188-7c3b7c5eb6e3"
        if($Description)
        {
            $descriptionContainer = $xml.CreateElement('container')
            $descriptionContainer.SetAttribute('name', 'Description')
            $descriptionContainer.SetAttribute('id', '2a7a09ae-54f3-468b-a188-7c3b7c5eb6e3')
            $descriptionScript = $xml.CreateElement('script')
            $scriptCData = $xml.CreateCDataSection($Description)
            
            $null = $descriptionScript.AppendChild($scriptCData)
            $null = $descriptionContainer.AppendChild($descriptionScript)
            $null = $infoContainer.AppendChild($descriptionContainer)
        }
        
        #container name="Required Snapins" id="2c4e1b31-79c0-46ad-aa27-eaacf1c10b59"
        $snapinsContainer = $xml.CreateElement('container')
        $snapinsContainer.SetAttribute('name', 'Required Snapins')
        $snapinsContainer.SetAttribute('id', '2c4e1b31-79c0-46ad-aa27-eaacf1c10b59')
        
        $null = $infoContainer.AppendChild($snapinsContainer)
        
        $snapinsItems = $xml.CreateElement('items')
        
        function RequiredSnapins
        {
            param(
                  [Parameter(Mandatory=$true)]
                  [String]
                  $Name,
                  [Parameter()]
                  [String]
                  $Type = 'Module',
                  [Parameter()]
                  [String]
                  $Author,
                  [Parameter()]
                  [String]
                  $Version
                 )
            $container = $xml.CreateElement('container')
            $container.SetAttribute('name', $Name)
            $container.SetAttribute('type', $Type)
            
            $containerItems = $xml.CreateElement('items')
            $null = $container.AppendChild($containerItems)
            
            $authorItem = $xml.CreateElement('item')
            $authorItem.SetAttribute('name', 'Author')
            $authorItem.SetAttribute('id', '514dab30-b238-4ae1-a6ac-38d5c3cfbed4')
            $authorValue = $xml.CreateElement('value')
            
            if($Author)
            {
                $authorValue.InnerText = $Author
            }
            
            $null = $authorItem.AppendChild($authorValue)
            $null = $containerItems.AppendChild($authorItem)
            
            $versionItem = $xml.CreateElement('item')
            $versionItem.SetAttribute('name', 'Version')
            $versionItem.SetAttribute('id', '8620403a-d313-44bb-8101-8b3090409c34')
            $versionValue = $xml.CreateElement('value')
            
            if($Version)
            {
                $versionValue.InnerText = $Version
            }
            
            $null = $versionItem.AppendChild($versionValue)
            $null = $containerItems.AppendChild($versionItem)
            $null = $snapinsItems.AppendChild($container)
        }
        
        & $Definition
        
        if($snapinsItems.container)
        {
            $null = $snapinsContainer.AppendChild($snapinsItems)
        }
        
        #container name="PowerPack Version" id="158620d6-6c0c-4c58-a3b0-8810fd17c3b1"
        $versionContainer = $xml.CreateElement('container')
        
        #container name="PowerPack CreateDate" id="81ad5d68-143b-4c79-8a95-bef6c941282b"
        $createDateContainer = $xml.CreateElement('container')
        
        #container name="Update URL" id="7600fdf1-ca11-4145-87fa-f3bc6b49d0f2"
        $urlContainer = $xml.CreateElement('container')
        
        #container name="PowerPack Home Page" id="8ae73fa1-67e8-4d3f-ad11-8245f7f5267f"
        $homePageContainer = $xml.CreateElement('container')
        
        #container name="PowerPack Icon" id="2840a004-5414-4758-b256-81fdcd9f8a87"
        $iconContainer = $xml.CreateElement('container')
        
        #container name="Console Version" id="7b082250-5a98-48f5-8a3f-6ab5f1e4d90e"
        $consoleVersionContainer = $xml.CreateElement('container')
        
    }
    
    $items = $xml.CreateElement('items')
    $null = $configuration.AppendChild($items)
    
    $navigationContainer =  $xml.CreateElement('container')
    $navigationContainer.SetAttribute('name', 'Navigation Tree')
    $navigationContainer.SetAttribute('id', 'b3b2283e-6f58-40c6-86b6-f01cd7f060fa')
    $null = $items.AppendChild($navigationContainer)
    
    $navigationItems = $xml.CreateElement('items')
    $null = $navigationContainer.AppendChild($navigationItems)
    
    $actionsContainer = $xml.CreateElement('container')
    $actionsContainer.SetAttribute('name', 'Actions')
    $actionsContainer.SetAttribute('id', '1ef02fe0-c6fc-4cdc-88bc-a9e4313bee18')
    $null = $items.AppendChild($actionsContainer)
    
    $actionsItems = $xml.CreateElement('items')   
    $null = $actionsContainer.AppendChild($actionsItems)
    
    #container name="Icons" id="9355c471-85b2-4b9a-92db-69873837cd8d"
    $iconsContainer = $xml.CreateElement('container')
    $iconsContainer.SetAttribute('name', 'Icons')
    $iconsContainer.SetAttribute('id','9355c471-85b2-4b9a-92db-69873837cd8d')
    $null = $items.AppendChild($iconsContainer)
    
    #container name="Types" id="37fc9e95-a3a2-4f53-a2d4-d29fe752995c"
    $typesContainer = $xml.CreateElement('container')
    $typesContainer.SetAttribute('name', 'Types')
    $typesContainer.SetAttribute('id', '37fc9e95-a3a2-4f53-a2d4-d29fe752995c')
    $null = $items.AppendChild($typesContainer)
    
    #container name="Scripts" id="c4ac93e0-f9c3-4e70-9e77-79210fee0239"
    $scriptsContainer = $xml.CreateElement('container')
    $scriptsContainer.SetAttribute('name', 'Scripts')
    $scriptsContainer.SetAttribute('id', 'c4ac93e0-f9c3-4e70-9e77-79210fee0239')
    $null = $items.AppendChild($scriptsContainer)
    
    #container name="Chart Presets" id="686d9542-3d11-48d0-bb48-f8a030b9963d"
    $chartsContainer = $xml.CreateElement('container')
    $chartsContainer.SetAttribute('name', 'Chart Presets')
    $chartsContainer.SetAttribute('id', '686d9542-3d11-48d0-bb48-f8a030b9963d')
    $null = $items.AppendChild($chartsContainer)
    
    function Action
    {
        param(
              [Parameter(Position=0, Mandatory=$true)]
              [String]
              $Name,
              [Parameter()]
              [String]
              $Id = [GUID]::NewGuid(),
              [Parameter()]
              [Bool]
              $RequireSelection = $false,
              [Parameter()]
              [String]
              $DisplayResults = "Refresh",
              [Parameter()]
              [ScriptBlock]
              $Command,
              [Parameter()]
              [ScriptBlock]
              $Script,
              [Parameter()]
              [PSObject[]]
              $Parameters,
              [Parameter()]
              [String]$Type
             )        
        $actionContainer = $xml.CreateElement("container")
        
        $actionContainer.SetAttribute("name", $Name)
        
        $actionContainer.SetAttribute("id", $Id)
        
        $actionContainer.SetAttribute("type",'Action@')
        
        if($RequireSelection)
        {
            $actionContainer.SetAttribute("RequireSelection", "Yes")
        }
        else
        {
            $actionContainer.SetAttribute("RequireSelection", "No")
        }
        
        # DisplayResults: Refresh, NestedView, LeaveAsIs
        
        $displayResultsValues = 'Refresh', 'NestedView', 'LeaveAsIs'
        
        if($displayResultsValues -contains $DisplayResults)
        {
        
        }
        else
        {
            Write-Error '-DisplayResults must be one of the following: Refresh, NestedView, LeaveAsIs'
        }
        
        function Command
        {
            param(
                  [Parameter()]
                  [String]
                  $Name
                 )
            
            #$xml = New-Object -TypeName System.Xml.XmlDocument
            
            $command = $xml.CreateElement("command")
            
            $command.SetAttribute("name", $Name)
            
            
            $null = $actionContainer.AppendChild($command)
        }
        
        $null = $actionsItems.AppendChild($actionContainer)
    }
    
    & $Definition
    
    return $xml
}